#ifndef INIT_H
#define INIT_H



#include "includes.h"



/** @brief Two dimensional array of elements of type T
*
*   \image html array2d.jpeg
*/
template< typename T >
class array2d
{

public:

	/** @brief Constructor creates empty array
	*	@param size_x dimension x of the array
	*	@param size_y dimension y of the array
	*/
	array2d( unsigned int size_x, unsigned int size_y )
	{
		arr = new T[ size_x * size_y ];
		s_x = size_x;
		s_y = size_y;
	};

	/** @brief Copy constructor
	*	@param a2d Array to copy
	*/
	array2d( const array2d< T >& a2d )
	{
		arr = new T[ a2d.s_x * a2d.s_y ];
		s_x = a2d.s_x;
		s_y = a2d.s_y;
		for ( unsigned int i = 0; i < ( s_x * s_y ); ++i )
			arr[ i ] = a2d.get( i );
	};

	//! @brief Destructor deletes the array
	~array2d()
	{
		delete [] arr;
	};

	/** @brief	Obtains element from the array by coordinates
	*	@param	x x coordinate of the element, constraint: x < size_x
	*	@param	y y coordinate of the element, constraint: y < size_y
	*	@return	requested element
	*/
	T get( unsigned int x, unsigned int y )
	{
		return arr[ x + ( y * s_x ) ];
	};

	/** @brief	Obtains element from the array by position
	*	@param	n position of the element, constraint: n < size_x + size_y
	*	@return	requested element
	*/
	T get( unsigned int n ) const
	{
		return arr[ n ];
	};


	/** @brief	Sets element to the array
	*	@param	o element to be set
	*	@param	x x coordinate of the element
	*	@param	y y coordinate of the element
	*	@return	true if storing successful, else false (position out of bounds)
	*/
	bool set( T o, unsigned int x, unsigned int y )
	{
		if ( ( x < s_x ) && ( y < s_y ) )
		{
			arr[ x + ( y * s_x ) ] = o;
			return true;
		}
		return false;
	};


private:

	//! main array
	T* arr;
	//! dimension x of the array
	unsigned int s_x;
	//! dimension y of the array
	unsigned int s_y;

};



/** @brief Class storing game parameters
*
*   \image html parameters.jpeg
*/
class parameters
{

public:

	/**	@brief	Function for obaining the singleton
	*	@return	pointer to the singleton
	*/
	static parameters* get_instance();

	//! @brief Nothing to be done here
	void rebuild() {};

	/** @brief	Loads all application's parameters from file
	*	@param	file filename, where the parameters are stored
	*	file structure: "Cathegory	Subcathegory(only by AI cathegory)	Name	Value"
	*	Cathegories: AI, GAME, GUI, SERVER
	*	#: comment
	*	@return	true, if loading is successful, else false
	*/
	bool load_parameters( const char* file );


	//! map of game parameters < name, value >
	map< string, unsigned int > game_parameters;
	//! map of gui parameters < name, value >
	map< string, unsigned int > gui_parameters;
	//! map of ai parameters < subcategory < name, value > >
	map< string, map< string, double > > ai_parameters;
	//! map of server parameters < name, value >
	map< string, unsigned int > network_parameters;


	static const unsigned int DEFINED_PLAYERS_RESOURCES = 3;


	int x;

private:

	parameters( int _x ): x( _x ) {};
	parameters( const parameters& );
	parameters& operator=( const parameters& x );
	//! @brief Nothing to be done here
	~parameters() {};


	/** @brief	Parses lines when loading parameters
	*	@param	pl line to parse
	*	@return	true if parsing successful, else false
	*/
	bool parse_param_line( const string& pl );
	/** @brief	Checks if all needed parameters are loaded successfully
	*	@return	true, if all parameters all present, else false
	*/
	bool check_parameters();
	/**	@brief	Checks if all parameters have suitable values
	*	if any parameter has not suitable value, corrects it
	*	@return	true, if everything is ok, false, if some parameter was corrected
	*/
	bool check_values();

};



#endif